using System;

using PowerPoint = Microsoft.Office.Interop.PowerPoint;
using Graph = Microsoft.Office.Interop.Graph;
using System.Runtime.InteropServices;

using Outcoding.GraphGenerator.Entities;
using Outcoding.GraphGenerator.Composition;
using Outcoding.GraphGenerator.Util.Logging;

namespace Outcoding.GraphGenerator.Generator {
    public class ChartGeneratorManager {

        #region Events

        public event PresentationParsedHandler PresentationParsed;

        #endregion

        #region Event Handlers

        protected void OnPresentationParsed(object sender, PresentationParsedEventArgs args) {
            LogManager.Instance.LogInfo("Presentation parsed");
        }

        #endregion

        #region Init Methods

        private void Init() {
            PresentationParsed += new PresentationParsedHandler(OnPresentationParsed);
        }

        #endregion

        private string mDataSourcePath;

        private ChartGenerator mChartGenerator;

        private PowerPoint.Application mPPApplication;

        private PowerPoint._Presentation mPPPresentation;

        private Presentation mPresentation;

        public PowerPoint.Application PPApplication {
            get {
                return mPPApplication;
            }
        }

        public PowerPoint._Presentation PPPresentation {
            get {
                return mPPPresentation;
            }
        }

        public Presentation OutPresentation {
            get {
                return mPresentation;
            }
        }

        public ChartGeneratorManager(string dataSourcePath) {
            if (!string.IsNullOrEmpty(dataSourcePath))
                mDataSourcePath = dataSourcePath;
            else
                throw new ArgumentNullException("DataSource path cannot be null.");

            Init();
            //mChartGenerator = new ChartGenerator2003();
            mChartGenerator = new ChartGenerator();
        }

        public void CreatePresentation() {
            Composer composer = new Composer(mDataSourcePath);
            composer.Compose();
            mPresentation = composer.Product;

            //add introductory slide
            if (mPresentation.Industry.IsIntroductory) 
                this.InsertIntroductorySlide(mPresentation);

            NotifyPresentationParsed(mPresentation);

            if (mPresentation != null) {
                mChartGenerator.GeneratePresentation(mPresentation);

                mPPApplication = mChartGenerator.PPApplication;
                mPPPresentation = mChartGenerator.PPPresentation;
            }
        }

        private void InsertIntroductorySlide(Presentation presentation){
            Label label = new Label();
            label.FontName = presentation.Industry.FontName;
            label.FontSize = presentation.Industry.FontSize;
            label.IsFontBold = presentation.Industry.IsFontBold;
            label.IsFontItalic = presentation.Industry.IsFontItalic;
            label.IsFontUnderline = presentation.Industry.IsFontUnderline;
            label.HorizontalAlignment = presentation.Industry.HorizontalAlignment;
            label.Color = presentation.Industry.Color;
            label.IsVisible = true;
            label.Text = presentation.Industry.Name;

            Entities.Shape shape = new Outcoding.GraphGenerator.Entities.Shape();
            shape.Content = label;

            Slide introductory = new Slide();
            introductory.Layout = SlideLayout.ppLayoutTitle;
            introductory.Shapes.Add(shape);

            presentation.Slides.Insert(0, introductory);
        }

        private void NotifyPresentationParsed(Presentation presentation) {
            if (presentation != null)
                this.PresentationParsed(this, new PresentationParsedEventArgs(presentation.Industry.Name, presentation.Slides.Count));
            else
                this.PresentationParsed(this, new PresentationParsedEventArgs(string.Empty, 0));
        }

        public void AddObserver(IChartGeneratorObserver observer) {
            this.PresentationParsed += new PresentationParsedHandler(observer.OnPresentationParsed);
            this.mChartGenerator.SlideComposing += new SlideComposingHandler(observer.OnSlideComposing);
            this.mChartGenerator.SlideComposed += new SlideComposedHandler(observer.OnSlideComposed);
        }
    }
}
